home *** CD-ROM | disk | FTP | other *** search
/ Sprite 1984 - 1993 / Sprite 1984 - 1993.iso / src / boot / netBoot.new / sys / usecmd.c < prev    next >
C/C++ Source or Header  |  1990-12-19  |  11KB  |  393 lines

  1.  
  2. /*
  3.  * @(#)usecmd.c 1.1 86/09/27
  4.  * Copyright (c) 1986 by Sun Microsystems, Inc.
  5.  */
  6.  
  7. /*
  8.  * "U" monitor command
  9.  *
  10.  * Reports on, or changes, or changes baud rates of, I/O devices.
  11.  * Syntax: [abc] means exactly one of a, b, or c.
  12.  *        [ab~] means zero or one of a and b.
  13.  *
  14.  * u        report current state of world
  15.  * u[ab]    select uart a or b as input and output device
  16.  * u[ab]io    (same)
  17.  * u[ab][io]    select uart a or b as input or output device
  18.  * uk[i~]    select keyboard as input device (i ignored)
  19.  * us[o~]    select screen as output device (o ignored)
  20.  * usk        select screen and keyboard
  21.  * uks        (same)
  22.  * u[ab~]1200    select speed of uart, defaults to current input dev
  23.  *         supports the usual speeds.
  24.  * ue        echo input to output
  25.  * une        don't echo input to output
  26.  * u[ab~]r    Reset uart to default state, a la powerup.
  27.  * uu <addr>    Use uart at virtual address <addr>
  28.  *        If TRANSPAR is supported (it currently isn't):
  29.  * u[ab~]t    enter transparent mode to uart; defaults to b.
  30.  * ux<char>    use escape char from transparent mode (not w/INKEYB)
  31.  * uf        use flow control in transparent mode
  32.  * unf        don't.
  33.  */
  34.  
  35. #include "../sun3/sunmon.h"
  36. #include "../h/globram.h"
  37. #include "../sun3/cpu.misc.h"
  38. #include "../dev/zsreg.h"
  39. #include "../sun3/m68vectors.h"
  40. #include "../dev/saio.h"
  41. #include "../sun3/cpu.addrs.h"
  42. #include "../h/eeprom.h"
  43.  
  44. unsigned char peekchar(), getone();
  45.  
  46. #define SELDEFAULT    0xFF
  47.  
  48. char inchars[] = "kab";            /* InSource chars */
  49. char outchars[]= "sab";            /* OutSink chars */
  50. /* ***** End of order-dependent tables */
  51.  
  52. /* Generate a baud rate clock count from the baud rate */
  53. struct sptab {int speeds, counts};
  54. #define B(speed)    ZSTIMECONST(ZSCC_PCLK, speed)
  55.  
  56. struct sptab speedtab[] = {
  57.     0x76800, B(76800),
  58.     0x38400, B(38400),
  59.     0x19200, B(19200),
  60.     0x9600,  B(9600),
  61.     0x4800,  B(4800),
  62.     0x2400,  B(2400),
  63.     0x1200,  B(1200),
  64.     0x600,   B(600),
  65.     0x300,   B(300),
  66.     0x150,   B(150),
  67.     0x110,   B(110),
  68.     0,       0     };
  69.  
  70. /* 
  71.  *      This is the UART initialization table (DTR, RST are asserted). 
  72.  */
  73. unsigned char    uart_init[] = {
  74.     0,    ZSWR0_RESET_STATUS,    /* Be sure we're at WR0 */
  75.     9,    ZSWR9_RESET_WORLD,    /* Reset the world first */
  76. #define    uart_init_skip    4
  77.     0,    ZSWR0_RESET_STATUS,    /* Reset ext status int */
  78.     4,    ZSWR4_PARITY_EVEN|    /* Async mode, etc, etc, etc */
  79.         ZSWR4_1_STOP|
  80.         ZSWR4_X16_CLK,
  81.     3,    ZSWR3_RX_8,        /* 8-bit chars, no auto CD/CTS shake */
  82.     5,    ZSWR5_RTS|        /* Set RTS/DTR, xmit 8-bit chars */
  83.         ZSWR5_TX_8|
  84.         ZSWR5_DTR,
  85.     9,    ZSWR9_NO_VECTOR,    /* Don't try to respond to intacks */
  86.     11,    ZSWR11_TRXC_XMIT|    /* Output xmitter clock */
  87.         ZSWR11_TXCLK_BAUD|
  88.         ZSWR11_RXCLK_BAUD,
  89.     12,     B(9600),                /* Default baud rate */
  90.         13,     (B(9600))/256,          /* Ditto, high order */
  91.     14,    ZSWR14_BAUD_FROM_PCLK,    /* Baud Rate Gen source = CPU clock */
  92.     2,    EVEC_LEVEL6/4,        /* Int vector = level 6 autovec */
  93.     3,    ZSWR3_RX_8|        /* Enable receiver */
  94.         ZSWR3_RX_ENABLE,
  95.     5,    ZSWR5_RTS|        /* Enable transmitter */
  96.         ZSWR5_TX_ENABLE|
  97.         ZSWR5_TX_8|
  98.         ZSWR5_DTR,
  99.     14,    ZSWR14_BAUD_ENA|    /* Enable baud rate generator */
  100.         ZSWR14_BAUD_FROM_PCLK,
  101.     0,    ZSWR0_RESET_STATUS,    /* Reset status latches */
  102.     0,    ZSWR0_RESET_STATUS,    /* Reset status latcehs again */
  103. };
  104.  
  105. /*
  106.  *      This is the UART initialization table (no DTR, RST).
  107.  */
  108. unsigned char   uart_nodtr[] = {
  109.     0,      ZSWR0_RESET_STATUS,     /* Be sure we're at WR0 */
  110.     9,      ZSWR9_RESET_WORLD,      /* Reset the world first */
  111.     0,      ZSWR0_RESET_STATUS,     /* Reset ext status int */
  112.     4,      ZSWR4_PARITY_EVEN|      /* Async mode, etc, etc, etc */
  113.             ZSWR4_1_STOP|
  114.             ZSWR4_X16_CLK,
  115.     3,      ZSWR3_RX_8,             /* 8-bit chars, no auto CD/CTS shake */ 
  116.     5,      ZSWR5_TX_8,             /* Xmit 8-bit chars */
  117.     9,      ZSWR9_NO_VECTOR,        /* Don't try to respond to intacks */
  118.     11,     ZSWR11_TRXC_XMIT|       /* Output xmitter clock */
  119.             ZSWR11_TXCLK_BAUD|
  120.             ZSWR11_RXCLK_BAUD,
  121.     12,     B(9600),                /* Default baud rate */
  122.     13,     (B(9600))/256,          /* Ditto, high order */
  123.     14,     ZSWR14_BAUD_FROM_PCLK,  /* Baud Rate Gen source = CPU clock */
  124.     2,      EVEC_LEVEL6/4,          /* Int vector = level 6 autovec */
  125.     3,      ZSWR3_RX_8|             /* Enable receiver */
  126.             ZSWR3_RX_ENABLE,
  127.     5,      ZSWR5_TX_ENABLE|        /* Enable transmitter */
  128.             ZSWR5_TX_8,
  129.     14,     ZSWR14_BAUD_ENA|        /* Enable baud rate generator */
  130.             ZSWR14_BAUD_FROM_PCLK,
  131.     0,      ZSWR0_RESET_STATUS,     /* Reset status latches */
  132.     0,      ZSWR0_RESET_STATUS,     /* Reset status latcehs again */
  133. };
  134.  
  135. /*
  136.  * Reset a ZSCC chip or channel.
  137.  * The arguments are the chip "control" port address, and a flag:
  138.  * 0 to reset just that channel, 1 to reset the whole chip (hardware
  139.  * reset).
  140.  */
  141. void
  142. reset_uart(addr, wholechip)
  143.     register unsigned char *addr;
  144.     char wholechip;
  145. {
  146.     register unsigned char *p = uart_init;
  147.     register unsigned char *endtable = &uart_init[sizeof(uart_init)];
  148.  
  149.     /*
  150.      *    This confusing if statement is checking for when we
  151.      *    want to initialize the SCC ports with DTR & RTS
  152.        *    signals not asserted.  We want to use the alternate
  153.      *    UART initialization table when the EEPROM has been
  154.      *    set for Port A or Port B.  We will only follow the
  155.       *    EEPROM selection if we are NOT in diagnostic mode.
  156.      *    This modification was necessary for SunLink.
  157.      */
  158.  
  159.     if (((EEPROM->ee_diag.eed_ttya_def.eet_rtsdtr == NO_RTSDTR &&
  160.         addr == &SERIAL0_BASE[1].zscc_control) ||
  161.         (EEPROM->ee_diag.eed_ttyb_def.eet_rtsdtr == NO_RTSDTR &&  
  162.         addr == &SERIAL0_BASE[0].zscc_control)) &&
  163.         (get_enable() & 1) == 0) {
  164.         p = &uart_nodtr[0];
  165.         endtable = &uart_nodtr[sizeof(uart_nodtr)];
  166.     }
  167.  
  168.     if (!wholechip) 
  169.         p += uart_init_skip;
  170.  
  171.     for (; p < endtable ;) {
  172.         DELAY(2);
  173.         *addr = *p++;
  174.         DELAY(2);
  175.     }
  176.  
  177.     if (addr == &SERIAL0_BASE[0].zscc_control && (get_enable() & 1) != 0) {
  178.         *addr = 12;
  179.         DELAY(2);
  180.         *addr = B(1200); 
  181.                 DELAY(2);
  182.         *addr = 13; 
  183.                 DELAY(2);
  184.         *addr = (B(1200))/256;
  185.                 DELAY(2);
  186.     }
  187. }
  188.  
  189.  
  190. /*
  191.  * Interpret a command from the user.
  192.  */
  193. usecmd()
  194. {
  195.     register char c;
  196.     register struct sptab *sp;
  197.     register int speed;
  198.     register short selector = SELDEFAULT;
  199.     register char inputok=0, outputok=0;    
  200.  
  201. another_sel:
  202.     c = getone();
  203.     switch (c & UPCASE) {
  204.  
  205.     case 'A':
  206.         selector = INUARTA;
  207.         inputok = outputok = 1;
  208.         goto another_sel;
  209.  
  210.     case 'B':
  211.         selector = INUARTB;
  212.         inputok = outputok = 1;
  213.         goto another_sel;
  214.  
  215.     case 'K':
  216.         selector = INKEYB; 
  217.         inputok = 1;
  218.         goto another_sel;
  219.         /* The effect here is that "sk" or "ks" will leave selector at
  220.            INKEYB (which = OUTSCREEN) but will also set outputok. */
  221.  
  222.     case 'S':
  223.         selector = OUTSCREEN;
  224.         outputok = 1;
  225.         goto another_sel;
  226.         /* The effect here is that "sk" or "ks" will leave selector at
  227.            INKEYB (which = OUTSCREEN) but will also set outputok. */
  228.     }
  229.  
  230.     /*
  231.      * Now decode the function to perform.  Possible functions
  232.      * include printing, redirection, baudsetting, etc.
  233.      */
  234.  
  235.     switch (c & UPCASE) {
  236.  
  237.     case '\0':    
  238.         if (selector != SELDEFAULT) {
  239.             /* Set input and/or output to A, B, K, or S */
  240.             if (inputok)
  241.                 gp->g_insource = selector;
  242.             if (outputok)
  243.                 gp->g_outsink = selector;
  244.             break;
  245.         }
  246.  
  247.         /* Report current state of world */
  248.         printf ("u%ci, u%co, ua%x, ub%x, uu%x, u", 
  249.               inchars[gp->g_insource],
  250.                 outchars[gp->g_outsink],
  251.                        findspeed(INUARTA),
  252.                          findspeed(INUARTB),
  253.                            gp->g_inzscc);
  254.         if (gp->g_echo == 0) putchar ('n');
  255. #ifdef TRANSPAR
  256.         printf ("e, u");
  257.         if (gp->g_transpstate == 0) putchar ('n');
  258.         printf ("f, ux");
  259.         if (gp->g_insource == INKEYB) 
  260.             printf("{Setup+E}");
  261.         else {
  262.             c = gp->g_transpend;
  263.             if (c < ' ') {putchar ('^'); c+=64;}
  264.             putchar (c);
  265.         }
  266.         putchar ('\n');
  267. #else  TRANSPAR
  268.         printf ("e\n");
  269. #endif TRANSPAR
  270.         break;
  271.  
  272.     case 'I':
  273.         if (!inputok) goto invalid;
  274.         gp->g_insource = selector;
  275.         if ('O' == (UPCASE & peekchar() ) ) goto another_sel;
  276.         break;
  277.  
  278.     case 'O':
  279.         if (!outputok) goto invalid;
  280.         gp->g_outsink = selector;
  281.         if ('I' == (UPCASE & peekchar() ) ) goto another_sel;
  282.         break;
  283.  
  284. #ifdef TRANSPAR
  285.     case 'T':
  286.         if (selector != INUARTA) selector = INUARTB;
  287.         transparent (selector);
  288.         putchar('\n');
  289.         break;
  290. #endif TRANSPAR
  291.  
  292.     case 'N':
  293.         if (selector != SELDEFAULT)
  294.             goto invalid;
  295.         else {
  296.             c = UPCASE & getone();
  297.             if ('E' == c) gp->g_echo = 0;
  298. #ifdef TRANSPAR
  299.            else if ('F' == c) gp->g_transpstate = 0;
  300. #endif TRANSPAR
  301.            else goto invalid;
  302.         }
  303.         break;
  304.  
  305.     case 'E':
  306.         if (selector == SELDEFAULT)    gp->g_echo = 1;
  307.         else                goto invalid;
  308.         break;
  309.  
  310. #ifdef TRANSPAR
  311.     case 'F':
  312.         if (selector == SELDEFAULT)    gp->g_transpstate = -1;
  313.         else                goto invalid;
  314.         break;
  315.  
  316.     case 'X':
  317.         gp->g_transpend = getone();
  318.         break;
  319. #endif TRANSPAR
  320.  
  321.     case 'U':
  322.         /* Reset uart address */
  323.         speed = getnum();
  324.         if (speed != 0) {
  325.             gp->g_inzscc  = (struct zscc_device *)speed;
  326.             gp->g_outzscc = (struct zscc_device *)speed;
  327.         }
  328.         break;
  329.  
  330.     case 'R':
  331.         /* Reset uart channel specified */
  332.         if (selector == SELDEFAULT) selector = gp->g_insource;
  333.         reset_uart(&gp->g_inzscc[2-selector].zscc_control, 0);
  334.         break;
  335.  
  336.     default:
  337.         if ( (c>='0') && (c<='9') ) {
  338.             if (selector == SELDEFAULT)
  339.                 selector = gp->g_insource;
  340.             if (selector < INUARTA)
  341.                 goto invalid;
  342.             gp->g_lineptr--;    /* Push the char back */
  343.             speed = getnum();    /* we know it'll work */
  344.             for (sp = speedtab; ; sp++) {
  345.                 if (sp->speeds == speed) break;
  346.                 if (sp->speeds == 0) goto invalid;
  347.             }
  348.             /* Reload time constants for BRG in Uart chip */
  349.             /* Manual advises disabling BRG while doing this
  350.                to avoid burps.  Try it this way -- they say
  351.                it will work OK but might reload with half the
  352.                old and half the new time constant. */
  353.             gp->g_inzscc[2-selector].zscc_control = 12;
  354.             gp->g_inzscc[2-selector].zscc_control = sp->counts;
  355.             gp->g_inzscc[2-selector].zscc_control = 13;
  356.             gp->g_inzscc[2-selector].zscc_control = sp->counts>>8;
  357.             break;
  358.         }
  359. invalid:
  360.         printf ("Invalid selection\n");
  361.         return;
  362.     }
  363.  
  364.     if ('\0' != getone()) printf ("Extra chars in command\n");
  365. }
  366.  
  367.  
  368. /*
  369.  * Find and print the speed setting of Uart <selector>, which
  370.  * is one of INUARTA, INUARTB.
  371.  *
  372.  * If the speed is not in the table, return the counter value,
  373.  * which will be more useful than nothing (maybe).
  374.  */
  375.  
  376. int
  377. findspeed(selector)
  378.     int selector;
  379. {
  380.     register int count;
  381.     register struct sptab *cp;
  382.  
  383.             gp->g_inzscc[2-selector].zscc_control = 12;
  384.     count = gp->g_inzscc[2-selector].zscc_control;
  385.             gp->g_inzscc[2-selector].zscc_control = 13;
  386.     count+=(gp->g_inzscc[2-selector].zscc_control) << 8;
  387.  
  388.     for (cp = speedtab; ; cp++) {
  389.         if (cp->counts == count) return cp->speeds;
  390.         if (cp->speeds == 0) return count;
  391.     }
  392. }
  393.